/**
 * Description: 用来提供Portlet系统的根类。
 *
 * Copyright:  2002-2006
 * Last Modified: 2004-06-30
 *
 */
function Portlet() {}

/**
 * 构造函数。
 * @param parent    the parent of this portlet.
 * @param hn   the html node of this step
 */
Portlet.prototype.init = function (parent,hn) {
//    Function.assert(hn != null, "Portlet:hn can not be null");
//    if (!hn || !hn.getType) return;
//    if (hn.getType() != "Application")
//        this._parent = parent;
//	this._root = this._parent == null ? this:this._parent._root;
//    this._html = hn;
//    this._html.portlet = this;
//    window.top.application
    var oParent = this.getComp().getParent();
    if (oParent && oParent.getComponent()) {
        var parentComp = oParent.getComponent().getHandleClass();
        this._parent = parentComp;
    } else {
    	try {
    		this._parent = window.parent.application.getHandleClass();
    	} catch (e) {
    		this._parent = application.getHandleClass();
            console.error(e);
        }
    }
    this._collectDefs();
    this._regMsgHandlers(true);
	//卸载页面, 需要同时卸载掉接口
	var that = this;
	$(window).unload(function(){
		that._regMsgHandlers(false);
	});
}

//Portlet.prototype.getParent = function () {return this._parent;}
//Portlet.prototype.getHTML = function () {return this._html;}
//Portlet.prototype.getName = function () {return this.constructor.toString().split(" ")[1];}

///**
// * 找到包含指定HTML节点的Portlet并返回。
// */
//Portlet.findPortlet = function (hn) {
//	while (hn!=null && typeof(hn.portlet) =="undefined") {
//		hn = hn.parentElement;
//	}
//	return hn == null ? null : hn.portlet;
//}

///**
// * 找到当前事件对象所在的portlet
// */
//_this = function() {
//	return Portlet.findPortlet(event.srcElement);
//}

///**
// * 打开本Portlet对象，在init后调用。
// */
//Portlet.prototype.open = function () {
//}

Portlet.EXPORT_ALL = "MSG_EXPORT_ALL";

/**
 * 本Portlet定义的消息处理函数表，格式如下：
 * MSG_ID:消息处理函数。
 */
Portlet.HANDLER = {};
/**
 * 本Portlet对外暴露的消息处理函数表，格式如下：
 * MSG_ID:EXPORT_MSG_ID。
 */
Portlet.E_HANDLER = {"MSG_EXPORT_ALL" : null};
/**
 * 本Portlet对外暴露的参数定义，格式如下：
 *	参数名(代码使用): {
 *     name:string,describle:string,value:string,readonly:boolean
 * }
 */
Portlet.PARAM_DEFINE = {};
/**
 * 本Portlet输入接口定义, 格式如下:
 *  MSG_ID:{
 *     describle:string,data:{???}
 *  }
 *  data - 接口数据样例
 */
Portlet.HANDLER_DEFINE = {};
/**
 * 本Portlet输出接口定义，格式如下
 * MSG_ID:{
 * 	  describle:string
 * }
 */
Portlet.CHANDLER_DEFINE = {};

Portlet.exportHandlers = function (oHandlers) {
	var o = new Object();
	var a = Portlet.exportHandlers.arguments;
	for (var i = 0; i<a.length; i++) {
		if (typeof (a[i]) == "object") {
			for (var h in a[i]) {
				o[h] = null;
			}
		} else if (typeof (a[i]) == "string") {
			o[a[i]] = null;
		}
	}
	return o;
}

/**
 * 收集节点的所有HANDLER,E_HANDLER,E_COMMAND定义。
 */
Portlet.prototype._collectDefs = function () {
	var c = this.constructor;
	if (typeof(c._HANDLER) != "undefined") {
		//already collected
		return;
	}
	var aH=new Array(),aEH=new Array(),aEC=new Array();
	while (c!= null) {
		if (typeof (c.HANDLER) != "undefined") {
			aH[aH.length] = c.HANDLER;
		}
		if (typeof (c.E_HANDLER) != "undefined") {
			aEH[aEH.length] = c.E_HANDLER;
		}
		if (typeof (c.E_COMMAND) != "undefined") {
			aEC[aEC.length] = c.E_COMMAND;
		}
		if (typeof(c.base) == "undefined" ){
			break;
		}
		c = c.base;
		if (typeof (c) == "object") {
			c = c.constructor;
		}
		i++;
	}
	c = this.constructor;
	c._HANDLER = new Object();
	c._E_HANDLER = new Object();
	c._E_COMMAND = new Object();
	//collect all handlers
	var p;
	for (var i = aH.length-1; i>=0; i--) {
		for (var h in aH[i]) {
			if (typeof (aH[i][h])== "undefined") {
				throw new Error(0,"Message "+h+" has undefined handler for "+this.constructor.toString());
			} else {
				p = aH[i][h];
				if (p == null) {
					delete c._HANDLER[h];
				} else {
					c._HANDLER[h] = p;
				}
			}
		}
	}
	//collect all e_handlers
	for (var i = aEH.length-1; i>=0; i--) {
		for (var h in aEH[i]) {
			if (typeof (aEH[i][h])== "undefined") {
				delete c._E_HANDLER[h];
			} else {
				c._E_HANDLER[h] = aEH[i][h];
			}
		}
	}
	//collect all e_commands
	//for (var i = aEC.length-1; i>=0; i--) {
	//	for (var h in aEC[i]) {
	//		if (typeof (aEC[i][h])== "undefined") {
	//			delete c._E_COMMAND[h];
	//		} else {
	//			c._E_COMMAND[h] = aEC[i][h];
	//		}
	//	}
	//}
}

/**
 * 发送消息并立即返回。
 * @param oMessage	发送的消息
 * @param sCompID 给那个组件发送消息，如果为空，则抛到最后一个组件
 */
Portlet.prototype.postMessage = function (oMessage, sCompID) {
	if (sCompID) {
		var oComp = this.getComp().getElementById(sCompID);
		if (oComp) {
			oComp.getHandleClass().postMessage(oMessage);
		}
	}
	if (typeof(debug) != "undefined") {
		if (oMessage.id != "MSG_POPOVER_DESTORY" &&
			oMessage.id != "MSG_POPOVER_ISINITSUCCEED") {
			$("#widgetdebug-log").append(
				"<span>输出接口:" + JSON.stringify(oMessage) + "</span><br/>"
			)
		}
	}
	//获得排除接口组件
	var pt = this;
	var num = 0;
	while (pt != null && num < 10) {
		if (typeof (pt._oMsgH) != "undefined") {
			var funcs = pt._oMsgH[oMessage.id];
			if (funcs != null) {
				try {
					var data;
					for (var compid in funcs) {
						if (!this.getComp().hasExCHandler(oMessage.id, compid)) {
							data =  funcs[compid].call(pt._oMsgH[oMessage.id+"_POBJECT"][compid],oMessage);
						}
					}
					return data;
				} catch(e) {
					console.error("接口调用失败. id:" + oMessage.id + "错误信息:" + e);
					break;
				}
			}
		}
		num++;
		pt = pt._parent;
	}
	//window"对应的处理函数！";
}

/**
 * 发送消息并等待返回值。
 * @param oMessage	发送的消息
 * @return	消息函数执行后的返回值
 */
Portlet.prototype.sendMessage = function (oMessage, sCompID) {
	this.postMessage(oMessage, sCompID);
}

/**
 * 销毁接口
 */
Portlet.prototype.destoryMessage = function(id) {
	var func = this._oMsgH[id];
	if (func != null) {
		delete this._oMsgH[id];
		delete this._oMsgH[id + "_POBJECT"]
	}
}

/**
 * 允许动态注册消息处理函数
 * @param sMsgID	要取消的消息ID的处理函数
 * @param oFunc		要注册的成员函数
 * @param oInst		该函数所属的对象，缺省为当前对象
 * @param bReg	如果true表示注册，否则表示取消注册
 */
Portlet.prototype.regMsgHandler = function(sMsgID,oFunc,oInst,bReg) {
	//将handler注册到自己和所有祖先portlet上。
	if (typeof(oInst)=="undefined") {
		oInst = this ;
	}

	var pt = this;
    var num = 0;
	var compid = this.getComp().getID();
	do{
		if (typeof (pt._oMsgH) == "undefined") {
			pt._oMsgH = new Object();
		}
		if (bReg) {
			if (!pt._oMsgH[sMsgID]) {
				pt._oMsgH[sMsgID] = {};
			}
			if (!pt._oMsgH[sMsgID+"_POBJECT"]) {
				pt._oMsgH[sMsgID+"_POBJECT"] = {};
			}
			pt._oMsgH[sMsgID][compid] = oFunc;
			pt._oMsgH[sMsgID+"_POBJECT"][compid] = oInst;
		} else if (pt._oMsgH[sMsgID+"_POBJECT"] &&
			pt._oMsgH[sMsgID+"_POBJECT"][compid] == oInst) {
			delete pt._oMsgH[sMsgID][compid];
			delete pt._oMsgH[sMsgID+"_POBJECT"][compid];
		}
		sMsgID = this._getExport(sMsgID,pt.constructor._E_HANDLER);
		pt = pt._parent;
        num++;
        if (num > 10) break;
	} while (pt != null && sMsgID != null);
}

/**
 * 将本Portlet的消息函数表注册到跟节点上。
 * @param bReg	如果true表示注册，否则表示取消注册
 */
Portlet.prototype._regMsgHandlers = function (bReg) {
	//将所有的handler注册到自己和所有祖先portlet上。
	var a = this.constructor._HANDLER;
	for (var h in a) {
		this.regMsgHandler(h,a[h],this,bReg);
	}
}

Portlet.prototype._getExport = function(sCmdID,oExport) {
	if (typeof(oExport[Portlet.EXPORT_ALL]) == "undefined") {
		var sCmdIDE = oExport[sCmdID];
		if (typeof (sCmdIDE) == "undefined") {
			return null;
		} else {
			return  sCmdIDE == null? sCmdID : sCmdIDE;
		}
	} else {
		return sCmdID;
	}
}

Portlet.prototype.setComp = function(oComp) {
    this._component = oComp;
}

Portlet.prototype.getComp = function() {
    return this._component;
}

